package com.dubbo.common.sms;

import java.text.SimpleDateFormat;
import java.util.Date;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsResponse;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;


/**
 * 阿里大于短信工具
 * <p>短信API产品的DEMO程序,工程中包含了一个SmsDemo类，直接通过
 * 执行main函数即可体验短信产品API功能(只需要将AK替换成开通了云通信-短信产品功能的AK即可) 工程依赖了2个jar包(存放在工程的libs目录下)
 * 1:aliyun-java-sdk-core.jar 2:aliyun-java-sdk-dysmsapi.jar</p>
 * @author chenwei
 * @date 2018年5月3日 下午3:35:00
 */
public class SMSUtil {
	
	/** 随机数返回的验证码 */
	private String verificationCode;

	public String getVERIFICATIONCODE() {
		return verificationCode;
	}
	/**自定义id*/
	private static final String OUT_ID = "yourOutId";
	private static final String DEFAULT_CONNECT_TIMEOUT = "sun.net.client.defaultConnectTimeout";
	private static final String DEFAULT_READ_TIMEOUT = "sun.net.client.defaultReadTimeout";
	private static final String TIMEOUT = "10000";
	/**节点地址名*/
	private static final String NODE_ADDRESS = "cn-hangzhou";
	/**日期格式*/
	private static final String DATE_FORMAT = "yyyyMMdd";
	/**每页显示10条*/
	private static final long PAGE_SIZE = 10L;
	/**开始页数*/
	private static final long CURRENT_PAGE = 1L;

	/** 密匙id */
	private String accessKeyId;
	/** 密匙 */
	private String accessKeySecret;
	/** 短信模版 */
	private String templateCode;
	/** 短信名称 */
	private String smsTitle;
	/** 模版收信人变量 */
	private String userName;
	/** 模版验证码变量 */
	private String code;

	/**
	 * 收信人名(可以从用户 表中查找)
	 */
	private String name;

	/**
	 * 需要发验证码的用户电话
	 */
	private String phone;

	/**
	 * 必要的参数传入,请参照短信参数表sms_param
	 * 
	 * @param String
	 *            keyId 密匙id(不能为null)
	 * @param String
	 *            keySecret 密匙(不能为null)
	 * @param String
	 *            templateCode 短信模版(不能为null)
	 * @param String
	 *            smsTitle 短信名称(不能为null)
	 * @param String
	 *            userName 模版收信人变量(收信人和验证码必须有一个不能为空)
	 * @param String
	 *            code 模版验证码变量(收信人和验证码必须有一个不能为空)
	 * @param String
	 *            phone 模版验证码变量(不能为null)
	 * @param String
	 *            name 模版验证码变量(根据短信模版是否有收件人模版变量添加)
	 * @param String
	 *            verificationCode 自定义验证码(可以使用getRandom()方法获得)
	 */
	public SMSUtil(String keyId, String keySecret, String templateCode, String smsTitle, String userName, String code,
			String phone, String name, String verificationCode) {
		this.accessKeyId = keyId;
		this.accessKeySecret = keySecret;
		this.templateCode = templateCode;
		this.smsTitle = smsTitle;
		this.verificationCode = verificationCode;

		if (userName == null || userName.replaceAll(" ", "").isEmpty() || userName.isEmpty()) {
			this.userName = "name";
		} else {
			this.userName = userName;
		}

		if (code == null || code.replaceAll(" ", "").isEmpty() || code.isEmpty()) {
			this.code = "code";
		} else {
			this.code = code;
		}

		this.phone = phone;

		if (name == null || name.replaceAll(" ", "").isEmpty() || name.isEmpty()) {
			this.name = "先生/女士";
		} else {
			this.name = name;
		}

	}

	/**
	 * @return the accessKeyId
	 */
	public String getAccessKeyId() {
		return accessKeyId;
	}

	/**
	 * @param accessKeyId
	 *            the accessKeyId to set
	 */
	public void setAccessKeyId(String accessKeyId) {
		this.accessKeyId = accessKeyId;
	}

	/**
	 * @return the accessKeySecret
	 */
	public String getAccessKeySecret() {
		return accessKeySecret;
	}

	/**
	 * @param accessKeySecret
	 *            the accessKeySecret to set
	 */
	public void setAccessKeySecret(String accessKeySecret) {
		this.accessKeySecret = accessKeySecret;
	}

	/**
	 * @return the templateCode
	 */
	public String getTemplateCode() {
		return templateCode;
	}

	/**
	 * @param templateCode
	 *            the templateCode to set
	 */
	public void setTemplateCode(String templateCode) {
		this.templateCode = templateCode;
	}

	/**
	 * @return the smsTitle
	 */
	public String getSmsTitle() {
		return smsTitle;
	}

	/**
	 * @param smsTitle
	 *            the smsTitle to set
	 */
	public void setSmsTitle(String smsTitle) {
		this.smsTitle = smsTitle;
	}

	/**
	 * @return the userName
	 */
	public String getUserName() {
		return userName;
	}

	/**
	 * @param userName
	 *            the userName to set
	 */
	public void setUserName(String userName) {
		this.userName = userName;
	}

	/**
	 * @return the code
	 */
	public String getCode() {
		return code;
	}

	/**
	 * @param code
	 *            the code to set
	 */
	public void setCode(String code) {
		this.code = code;
	}

	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * @param name
	 *            the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * @return the phone
	 */
	public String getPhone() {
		return phone;
	}

	/**
	 * @param phone
	 *            the phone to set
	 */
	public void setPhone(String phone) {
		this.phone = phone;
	}

	// 产品名称:云通信短信API产品,开发者无需替换
	private static final String product = "Dysmsapi";
	// 产品域名,开发者无需替换
	private static final String domain = "dysmsapi.aliyuncs.com";

	// TODO 此处需要替换成开发者自己的AK(在阿里云访问控制台寻找)
	// private String accessKeyId = keyId;
	// private String accessKeySecret = keySecret;

	/**
	 * 发送短息
	 * 
	 * @return
	 * @throws ClientException
	 */
	public SendSmsResponse sendSms() throws ClientException {
		return this.getIAcsClient().getAcsResponse(getSendSmsRequest());
	}

	private SendSmsRequest getSendSmsRequest() {
		// 组装请求对象-具体描述见控制台-文档部分内容
		SendSmsRequest request = new SendSmsRequest();
		// 必填:待发送手机号
		request.setPhoneNumbers(phone);
		// 必填:短信签名-可在短信控制台中找到
		request.setSignName(smsTitle);
		// 必填:短信模板-可在短信控制台中找到
		request.setTemplateCode(templateCode);
		// 可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
		request.setTemplateParam("{\"" + ((userName == null) ? "name" : userName) + "\":\""
				+ ((name == null) ? "name" : name) + "\", \"" + code + "\":\"" + verificationCode + "\"}");
		// 选填-上行短信扩展码(无特殊需求用户请忽略此字段)
		// request.setSmsUpExtendCode("90997");

		// 可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
		request.setOutId(OUT_ID);
		return request;
	}
	
	private IAcsClient getIAcsClient() throws ClientException {
		// 可自助调整超时时间
		System.setProperty(DEFAULT_CONNECT_TIMEOUT, TIMEOUT);
		System.setProperty(DEFAULT_READ_TIMEOUT, TIMEOUT);

		// 初始化acsClient,暂不支持region化
		IClientProfile profile = DefaultProfile.getProfile(NODE_ADDRESS, accessKeyId, accessKeySecret);
		DefaultProfile.addEndpoint(NODE_ADDRESS, NODE_ADDRESS, product, domain);
		IAcsClient acsClient = new DefaultAcsClient(profile);
		return acsClient;
	}
	/**
	 * 发送短息
	 *
	 * @author lihongwu
	 * 2019年2月26日 上午11:58:58
	 * @param templateParam 模板
	 * @return
	 * @throws ClientException
	 */
	public SendSmsResponse sendSms(String templateParam) throws ClientException {
		SendSmsRequest sendSmsRequest = this.getSendSmsRequest();
		sendSmsRequest.setTemplateParam(templateParam);
		return this.getIAcsClient().getAcsResponse(sendSmsRequest);
	}
	/**
	 * 查询发送详细信息
	 * 
	 * @author chenwei
	 * @date 2019年2月26日 下午2:24:10
	 * @param bizId 可选-流水号
	 * @return
	 * @throws ClientException
	 */
	public QuerySendDetailsResponse querySendDetails(String bizId) throws ClientException {
		IAcsClient acsClient = this.getIAcsClient();
		// 组装请求对象
		QuerySendDetailsRequest request = new QuerySendDetailsRequest();
		// 必填-号码
		request.setPhoneNumber(phone);
		// 可选-流水号
		request.setBizId(bizId);
		// 必填-发送日期 支持30天内记录查询，格式yyyyMMdd
		SimpleDateFormat ft = new SimpleDateFormat(DATE_FORMAT);
		request.setSendDate(ft.format(new Date()));
		// 必填-页大小
		request.setPageSize(PAGE_SIZE);
		// 必填-当前页码从1开始计数
		request.setCurrentPage(CURRENT_PAGE);

		// hint 此处可能会抛出异常，注意catch
		return acsClient.getAcsResponse(request);
	}
	
	/**
	 * 实例化阿里大于短信工具
	 * 
	 * @param keyId 密匙id(不能为null)
	 * @param keySecret 密匙(不能为null)
	 * @param templateCode 短信模版(不能为null)
	 * @param smsTitle 短信名称(不能为null)
	 * @param userName 模版收信人变量(收信人和验证码必须有一个不能为空)
	 * @param code 模版验证码变量(收信人和验证码必须有一个不能为空)
	 * @param phone 模版验证码变量(不能为null)
	 * @param name 模版验证码变量(根据短信模版是否有收件人模版变量添加)
	 * @param verificationCode 随机数 可用随机数工具类生成
	 * @return 短信工具对象
	 */
	public static SMSUtil instantiation(String keyId, String keySecret, String templateCode, String smsTitle, String userName, String code,
			String phone, String name,String verificationCode){
		return new SMSUtil(keyId, keySecret, templateCode, smsTitle, userName, code, phone, name,verificationCode);
	}

	/** 测试代码 */
	// public void demo1() throws ClientException, InterruptedException {
	//
	// // 发短信
	// SendSmsResponse response = sendSms();
	// System.out.println("短信接口返回的数据----------------");
	// System.out.println("Code=" + response.getCode());
	// System.out.println("Message=" + response.getMessage());
	// System.out.println("RequestId=" + response.getRequestId());
	// System.out.println("BizId=" + response.getBizId());
	//
	// Thread.sleep(3000L);
	//
	// // 查明细
	// if (response.getCode() != null && response.getCode().equals("OK")) {
	// QuerySendDetailsResponse querySendDetailsResponse =
	// querySendDetails(response.getBizId());
	// System.out.println("短信明细查询接口返回数据----------------");
	// System.out.println("Code=" + querySendDetailsResponse.getCode());
	// System.out.println("Message=" + querySendDetailsResponse.getMessage());
	// int i = 0;
	// for (QuerySendDetailsResponse.SmsSendDetailDTO smsSendDetailDTO :
	// querySendDetailsResponse
	// .getSmsSendDetailDTOs()) {
	// System.out.println("SmsSendDetailDTO[" + i + "]:");
	// System.out.println("Content=" + smsSendDetailDTO.getContent());
	// System.out.println("ErrCode=" + smsSendDetailDTO.getErrCode());
	// System.out.println("OutId=" + smsSendDetailDTO.getOutId());
	// System.out.println("PhoneNum=" + smsSendDetailDTO.getPhoneNum());
	// System.out.println("ReceiveDate=" + smsSendDetailDTO.getReceiveDate());
	// System.out.println("SendDate=" + smsSendDetailDTO.getSendDate());
	// System.out.println("SendStatus=" + smsSendDetailDTO.getSendStatus());
	// System.out.println("Template=" + smsSendDetailDTO.getTemplateCode());
	// }
	// System.out.println("TotalCount=" + querySendDetailsResponse.getTotalCount());
	// System.out.println("RequestId=" + querySendDetailsResponse.getRequestId());
	// }
	//
	// }
	//
	// public void demo2() {
	// System.out.println(accessKeyId);
	// System.out.println(accessKeySecret);
	// System.out.println(templateCode);
	// System.out.println(smsTitle);
	// System.out.println(userName);
	// System.out.println(code);
	// System.out.println(name);
	// System.out.println(phone);
	// }
}
